package com.way.fileexplorer.activities;

import java.io.File;
import java.util.ArrayList;

import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.way.fileexplorer.R;
import com.way.fileexplorer.StorageReceiver;
import com.way.fileexplorer.adapters.CopyDestListAdapter;
import com.way.fileexplorer.fragments.BaseFragment;
import com.way.fileexplorer.fragments.DetailedListFragment;
import com.way.fileexplorer.fragments.ExternalStorageExplorerFragment;
import com.way.fileexplorer.fragments.InternalStorageExplorerFragment;
import com.way.fileexplorer.fragments.OverViewFragment;
import com.way.fileexplorer.util.ActivityUtils;
import com.way.fileexplorer.util.FileSort;
import com.way.fileexplorer.util.FileType;
import com.way.fileexplorer.util.FileUtil;
import com.way.fileexplorer.util.NotifyManager;
import com.way.fileexplorer.util.Slog;
import com.way.fileexplorer.util.StorageUtil;

public class FileExploreActivity extends FragmentActivity {

	private static final String TAG = "FileExploreActivity";

	private static final int TAB_INDEX_OVERVIEW_DEFAULT = 0;
	private static final int TAB_INDEX_INTERNALVIEW_DEFAULT = 1;
	private static final int TAB_INDEX_EXTERNALVIEW_DEFAULT = 2;
	private static final int TAB_INDEX_SEARCHVIEW_DEFAULT = 3;
	private static final int TAB_COUNTS_DEFAULT = 4;
	private static final int TAB_INDEX_INVALID = -1;

	private static int mTabIndexOverView = TAB_INDEX_OVERVIEW_DEFAULT;
	private static int mTabIndexInternalView = TAB_INDEX_INTERNALVIEW_DEFAULT;
	private static int mTabIndexExternalView = TAB_INDEX_EXTERNALVIEW_DEFAULT;
	private static int mTabIndexSearchView = TAB_INDEX_SEARCHVIEW_DEFAULT;
	private static int mTabCounts = TAB_COUNTS_DEFAULT;

	private static boolean mTabExternalReady = false;
	private static boolean mTabInternalReady = false;

	private ArrayList<BaseFragment> mFragmentList = new ArrayList<BaseFragment>();
	private BaseFragment mCurrentFragment;
	private TextView mPathBar;

	private boolean mIsPagerDirty = false;
	private static File mInternalCurrentPath;
	private static File mExternalCurrentPath;

	ActionBar mActionBar;
	/**
	 * The {@link android.support.v4.view.PagerAdapter} that will provide
	 * fragments for each of the sections. We use a
	 * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
	 * will keep every loaded fragment in memory. If this becomes too memory
	 * intensive, it may be best to switch to a
	 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
	 */
	SectionsPagerAdapter mSectionsPagerAdapter;

	/**
	 * The {@link ViewPager} that will host the section contents.
	 */
	ViewPager mViewPager;
	
	@Override
    protected void onNewIntent(Intent intent) {
	    Log.i(TAG,"onNewIntent");
	    checkPagerValid();
    }

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_file_explore);
		
		FileType.init(this);
		StorageUtil.init(this);
		NotifyManager.init(this);
		ActivityUtils.initAdapters(this);
		FileSort.getFileListSort().setSortType(FileSort.SORT_BY_NAME);
		final SharedPreferences settings = this.getSharedPreferences(
				FileSort.FILE_SORT_KEY, 0);
		settings.edit().putInt(FileSort.FILE_SORT_KEY, FileSort.SORT_BY_NAME)
				.commit();
		Log.i(TAG,"onCreate");
		mPathBar = (TextView) findViewById(R.id.path_bar_file_explore_activity);

		mActionBar = ActivityUtils.createActionBar(this,
				new NavigationCallback());
		mSectionsPagerAdapter = new SectionsPagerAdapter(
				getSupportFragmentManager());
		mViewPager = (ViewPager) findViewById(R.id.pager);
		mViewPager.setAdapter(mSectionsPagerAdapter);
	}

	public void moveToExternal(File currentPath) {
		if (mTabIndexExternalView != TAB_INDEX_INVALID) {
			mViewPager.setCurrentItem(mTabIndexExternalView);
			((DetailedListFragment) mFragmentList.get(mTabIndexExternalView))
					.getAdapter().setCurrentPath(currentPath);
		}
	}

	public void moveToInternal(File currentPath) {
		if (mTabIndexInternalView != TAB_INDEX_INVALID) {
			mViewPager.setCurrentItem(mTabIndexInternalView);
			((DetailedListFragment) mFragmentList.get(mTabIndexInternalView))
					.getAdapter().setCurrentPath(currentPath);
		}
	}

	/**
	 * The {@link StorageReceiver} that receive SDCard mounting action, and call
	 * this back. TODO:We should add our protection and UI changing here, like
	 * cancel copy and paste and others.
	 */
	public void onStorageChanged() {
		checkPagerValid();
		invalidateOptionsMenu();
	}

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if(menu != null){
            menu.clear();
        }
        if(StorageUtil.getInternalStorageState().equals("mounted") || StorageUtil.getExternalStorageState().equals("mounted")){
            getMenuInflater().inflate(R.menu.main, menu);
        }
        return true;
    }
	/**
	 * checkPagerValid is a protection, if mounting were changed or other
	 * condition, we call this, and call
	 * {@link FileExploreActivity#updatePagerIndex()} to refresh
	 * {@link FileExploreActivity#mFragmentList}
	 */
	void checkPagerValid() {
		Slog.d(TAG, "checkPagerValid Enter");
		boolean internalReady = StorageUtil.getInternalStorageState().equals(
				"mounted");
		boolean externalReady = StorageUtil.getExternalStorageState().equals(
				"mounted");
		boolean notifyChange = false;
		if (mViewPager != null) {
			if (mTabExternalReady != externalReady
					|| mTabInternalReady != internalReady) {
				Slog.d("notifyChange = true");
				notifyChange = true;
			}
		}
		mTabExternalReady = externalReady;
		mTabInternalReady = internalReady;
		updatePagerIndex(notifyChange);
		if (notifyChange) {
			mSectionsPagerAdapter.notifyDataSetChanged();
			mViewPager.setAdapter(mSectionsPagerAdapter);
		} else {
			mIsPagerDirty = true;
		}
		if (mCurrentFragment == null) {
			mCurrentFragment = (BaseFragment) mSectionsPagerAdapter.getItem(0);
		}
		mPathBar.setText(mCurrentFragment == null ? getString(R.string.title_section_overview)
				: mCurrentFragment.getCurrentString());
		setActionBarCurrentIcon();
	}

	/**
	 * This method can refresh current {@link FileExploreActivity#mFragmentList}
	 * and set {@link FileExploreActivity#mSectionsPagerAdapter} to
	 * {@link FileExploreActivity#mViewPager}
	 */
	void updatePagerIndex(boolean notifyChange) {
		ArrayList<String> navigationList = new ArrayList<String>();
		ArrayList<String> searchList = new ArrayList<String>();
		if (mViewPager != null && notifyChange) {
			mViewPager.setCurrentItem(0);
		}
		if(mFragmentList != null){
		    mFragmentList.clear();
	        int count = 1;
	        mFragmentList.add(OverViewFragment.getInstance(this));
	        navigationList.add(getString(R.string.title_section_overview));
	        searchList.add(getString(R.string.title_section_all));
	        if (mTabInternalReady) {
	            Log.i(TAG, "internal storage is mount");
	            mTabIndexInternalView = mTabIndexOverView + 1;
	            mFragmentList
	                    .add(InternalStorageExplorerFragment.getInstance(this));
	            navigationList.add(getString(R.string.title_section_internal));
	            searchList.add(getString(R.string.title_section_internal));
	            count++;
	        } else {
	            Log.i(TAG, "internal storage is umount");
	            mTabIndexInternalView = TAB_INDEX_INVALID;
	        }

	        if (mTabExternalReady) {
	            Log.i(TAG, "external storage is mount");
	            mFragmentList
	                    .add(ExternalStorageExplorerFragment.getInstance(this));
	            mTabIndexExternalView = mTabInternalReady ? mTabIndexInternalView + 1
	                    : mTabIndexOverView + 1;
	            navigationList.add(getString(R.string.title_section_external));
	            searchList.add(getString(R.string.title_section_external));
	            count++;
	        } else {
	            Log.i(TAG, "external storage is unmount");
	            mTabIndexExternalView = TAB_INDEX_INVALID;
	            searchList.remove(0);
	        }

	        mTabCounts = count;
	        ActivityUtils.setNavigationList(navigationList);
	        ActivityUtils.setSearchLocation(searchList);
	        Slog.d("count=" + count);
	        
		}
		
	}

	/**
	 * We use this to manage our fragments. A {@link FragmentPagerAdapter} that
	 * returns a fragment corresponding to one of the sections/tabs/pages.
	 */
	public class SectionsPagerAdapter extends FragmentPagerAdapter {
		int mPosition;

		public SectionsPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		/**
		 * Get current displaying fragment.
		 * 
		 * @return All fragments appear in this application should be extended
		 *         from {@link BaseFragment}
		 */
		public BaseFragment getCurrentFragment() {
			return (BaseFragment) getItem(mPosition);
		}

		@Override
		public Fragment getItem(int position) {
			return mFragmentList.get(position);
		}

		/**
		 * Override this method to set the title of ActionBar
		 * 
		 * @Override {@link FragmentPagerAdapter#setPrimaryItem(ViewGroup, int, Object)}
		 */
		public void setPrimaryItem(ViewGroup container, int position,
				Object object) {
			// Slog.d("setPrimaryItem position=" + position);
			mPosition = position;
			super.setPrimaryItem(container, position, object);
		}

		public void notifyDataSetChanged(Bundle data) {
			notifyDataSetChanged();
		}

		@Override
		public void notifyDataSetChanged() {
			super.notifyDataSetChanged();
			mIsPagerDirty = false;
		}

		@Override
		public int getCount() {
			return mTabCounts;
		}

		@Override
		public CharSequence getPageTitle(int position) {
			if (mTabIndexOverView == position) {
				return getText(R.string.title_section_overview);
			} else if (mTabIndexExternalView == position) {
				return getText(R.string.title_section_external);
			} else if (mTabIndexInternalView == position) {
				return getText(R.string.title_section_internal);
			} else if (mTabIndexSearchView == position) {
				return getText(R.string.title_section_external);
			} else {
				Slog.e("Bad position =" + position + "check your getCount");
				throw new IllegalStateException();
			}
		}
	}
	@Override
	protected void onStart() {
	    Log.i(TAG,"onStart");
	    checkPagerValid();
	    super.onStart();
	}

	@Override
	protected void onResume() {
	    Log.i(TAG,"onResume");
		if (mIsPagerDirty) {
			mSectionsPagerAdapter.notifyDataSetChanged();
		}
	      mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
	            @Override
	            public void onPageScrollStateChanged(int arg0) {}

	            @Override
	            public void onPageScrolled(int arg0, float arg1, int arg2) {    }

	            @Override
	            public void onPageSelected(int position) {
	                if (position < 0){
	                    return;
	                }                   
	                Slog.i(TAG, "onPageSelected position is"+ position);
	                if(mActionBar == null){
	                    mActionBar = ActivityUtils.createActionBar(FileExploreActivity.this,
	                            new NavigationCallback());
	                }
	                mActionBar.setSelectedNavigationItem(position);
	                mCurrentFragment = (BaseFragment) mSectionsPagerAdapter
	                        .getItem(position);
	                mPathBar.setText(mCurrentFragment.getCurrentString());
	                if (position == 0) {
	                    mPathBar.setVisibility(View.GONE);
	                } else {
	                    ((DetailedListFragment) mCurrentFragment).update();
	                    mPathBar.setVisibility(View.VISIBLE);
	                }
	                setActionBarCurrentIcon();
	            }
	        });
	        checkPagerValid();
		if(mSectionsPagerAdapter != null){
            mSectionsPagerAdapter.notifyDataSetChanged();
        }
		super.onResume();
	}
	
	@Override
	protected void onStop() {
		super.onStop();
	}

	@Override
	protected void onDestroy() {
		Slog.e("onDestroy");
		Slog.stopTracing();
		super.onDestroy();
	}

	@Override
	public void finish() {
		moveTaskToBack(true);
	}

	private void setActionBarCurrentIcon() {
		if (mCurrentFragment != null && this.mActionBar != null) {
			mActionBar.setIcon(mCurrentFragment.getIcon());
			boolean bHidePath = mCurrentFragment.hidePath();
			if (bHidePath) {
				mPathBar.setVisibility(View.GONE);
			} else {
				mPathBar.setVisibility(View.VISIBLE);
			}
		}
	}

	/**
	 * When back key pressed, we call every {@link BaseFragment#onBackPressed}
	 * in current displaying fragment
	 */
	public void onBackPressed() {
		processBackKey();
	}

	private void processBackKey() {
		if(mSectionsPagerAdapter != null){
			if (mSectionsPagerAdapter.getCurrentFragment().onBackPressed()) {
				NotifyManager.getInstance(this).getExitDialog().show();
			}
		}
	}

	public void onPathChanged(File file, boolean isExternal) {
		if (isExternal) {
			mExternalCurrentPath = file;
			mActionBar.setTitle(mExternalCurrentPath.getPath());
		} else {
			mInternalCurrentPath = file;
		}
	}

	public File getCurrentPath(File file, boolean isExternal) {
		if (isExternal) {
			return mExternalCurrentPath;
		} else {
			return mInternalCurrentPath;
		}
	}

	// TODO: IN FUTURE VERSIONS, overview page will not have paste function.
	public void onActionMode() {

	}

	public class NavigationCallback implements ActionBar.OnNavigationListener {
		@Override
		public boolean onNavigationItemSelected(int itemPosition, long itemId) {
			if (FileExploreActivity.this.mViewPager != null) {
				if (FileExploreActivity.this.mViewPager.getCurrentItem() != FileExploreActivity.this
						.getActionBar().getSelectedNavigationIndex())
					FileExploreActivity.this.mViewPager
							.setCurrentItem(itemPosition);
			}
			return true;
		}
	}

	public void setPathBarString(String text) {
		if(mPathBar != null && text != null && !text.isEmpty()){
			mPathBar.setText(text);
		}
	}

	public BaseFragment getCurrentFragment() {
		return mCurrentFragment;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			processBackKey();
			return true;
		case R.id.action_settings:
			Intent intent = new Intent(this, SettingActivity.class);
			startActivity(intent);
			return true;
        case R.id.searchfile:
            this.startActivity(new Intent().setClass(
                    this.getApplicationContext(), FileSearchActivity.class));
            return true;
		}
		return super.onOptionsItemSelected(item);
	}

	public boolean isCurrentFragment(BaseFragment fragment) {
		if (fragment == mCurrentFragment) {
			return true;
		} else {
			return false;
		}
	}

	DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int which) {
			ActivityUtils.startPasteMode(which);
		}
	};

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
	    super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
        case DetailedListFragment.PASTE_PATH:
            if (resultCode == RESULT_OK) {
                if (data != null) {
                    final boolean isSdcard = data.getBooleanExtra("isSdStor", false);
                    mViewPager.setCurrentItem(isSdcard ? 2 : 1);
                    final File folderPath = new File(
                            data.getStringExtra("paste_path"));
                    if (getCurrentFragment() != null && ((DetailedListFragment) getCurrentFragment()).getAdapter() != null) {
                        ((DetailedListFragment) getCurrentFragment()).getAdapter().setCurrentPath(folderPath);
                        ((DetailedListFragment) getCurrentFragment()).getAdapter().refresh();
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                // TODO Auto-generated method stub
                                FileUtil.paste(isSdcard, FileExploreActivity.this, folderPath, ((DetailedListFragment) getCurrentFragment()).getAdapter());// bug 201956
                            }
                        }).start();
                    }
                }
            } else if (resultCode == DetailedListFragment.RESULT_RESELECT) {
                if (StorageUtil.getExternalStorageState().equals("mounted")) {
                    Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle(R.string.select_destination);
                    BaseAdapter adapter = new CopyDestListAdapter();
                    builder.setAdapter(adapter, listener);
                    builder.create().show();
                } else {
                    // TODO
                }
            } else {
                // TODO
            }
            break;
        }
	}
}
